﻿package net.wangit.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class FileUtil {

	private static final Log log = LogFactory
			.getLog(net.wangit.util.FileUtil.class);

	public FileUtil() {
	}

	public static final String[] listFiles(String path) {
		return list(path, false);
	}

	public static final String[] listDirectorys(String path) {
		return list(path, true);
	}

	private static final String[] list(String path, boolean isDirectory) {
		File directory = getDirectory(path);
		if (directory == null)
			return null;
		int count = 0;
		File files[] = directory.listFiles();
		String temp[] = new String[files.length];
		for (int i = 0; i < files.length; i++)
			if (files[i].isDirectory() == isDirectory) {
				temp[count] = files[i].getName();
				count++;
			}

		return ArrayUtil.cloneSubarray(temp, 0, count);
	}

	public static final String[] list(String path) {
		File file = getDirectory(path);
		if (file != null) {
			String list[] = file.list();
			return list;
		} else {
			return null;
		}
	}

	public static final File getDirectory(String path) {
		File file = new File(path);
		if (file.canRead() && file.isDirectory())
			return file;
		else
			return null;
	}

	public static boolean exists(String path) {
		File file = new File(formatPath(path));
		return file.exists();
	}
	
	/**
	 * 格式化路径
	 * @param path
	 * @return
	 */
	public static String formatPath(String path) {
		path = path.replace('\\', '/');
		return StringUtil.replace(path, "//", "/");
	}

	public static String read(String path) {
		StringBuffer content = new StringBuffer();
		try {
			RandomAccessFile file = new RandomAccessFile(formatPath(path), "r");
			long length = file.length();
			String oneline = "";
			for (long pointer = 0L; pointer < length; pointer = file
					.getFilePointer()) {
				oneline = file.readLine();
				content.append((new StringBuilder(String.valueOf(oneline)))
						.append("\n").toString());
			}

			file.close();
			return CodeUtil.ISO2GBK(content.toString());
		} catch (Exception ex) {
			log.error("FileUtil.read error");
			return null;
		}
	}

	public static void create(String path, String content) {
		try {
			rename(path, (new StringBuilder(String.valueOf(path))).append(
					".bak").toString());
			RandomAccessFile newfile = new RandomAccessFile(path, "rw");
			newfile.writeBytes(content);
			newfile.close();
		} catch (Exception ex) {
			ex.printStackTrace();
			log.error("FileUtil.create error");
		}
	}

	public static final boolean rename(String orgPathName, String tarPathName) {
		boolean result = false;
		try {
			File file = new File(orgPathName);
			file.renameTo(new File(tarPathName));
			result = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	public static final boolean delete(String path) {
		try {
			File file = new File(path);
			file.delete();
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public static boolean mkdirs(String path) {
		try {
			File dir = new File(path);
			dir.mkdirs();
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public static void copyDirectory(File srcDir, File destDir)
			throws IOException {
		copyDirectory(srcDir, destDir, false);
	}

	public static void copyDirectory(File srcDir, File destDir,
			boolean overwrite) throws IOException {
		File files[] = srcDir.listFiles();
		if (!destDir.exists())
			destDir.mkdirs();
		else
			log.debug((new StringBuilder(String.valueOf(destDir
					.getAbsolutePath()))).append(" already exists").toString());
		for (int i = 0; i < files.length; i++) {
			File file = files[i];
			File dest = new File(destDir, file.getName());
			if (file.isFile())
				copyFile(new FileInputStream(file), dest, overwrite);
			else
				copyDirectory(file, dest, overwrite);
		}

	}

	public static void copyFile(File srcFile, File destFile) throws IOException {
		InputStream input = new FileInputStream(srcFile);
		copyFile(input, destFile);
	}

	public static void copyFile(InputStream srcStream, File destFile)
			throws IOException {
		copyFile(srcStream, destFile, false);
	}

	public static void copyFile(InputStream srcStream, File destFile,
			boolean overwrite) throws IOException {
		File parentFile = destFile.getParentFile();
		if (!parentFile.isDirectory())
			parentFile.mkdirs();
		if (destFile.exists()) {
			if (overwrite) {
				log.debug((new StringBuilder("Overwriting file at: ")).append(
						destFile.getAbsolutePath()).toString());
				writeStreamToFile(srcStream, destFile);
			} else {
				log.warn((new StringBuilder(String.valueOf(destFile
						.getAbsolutePath()))).append(" already exists")
						.toString());
			}
		} else {
			destFile.createNewFile();
			writeStreamToFile(srcStream, destFile);
		}
	}

	private static void writeStreamToFile(InputStream srcStream, File destFile)
			throws IOException {
		OutputStream output;
		InputStream input;
		input = null;
		output = null;
		try {
			input = new BufferedInputStream(srcStream);
			output = new BufferedOutputStream(new FileOutputStream(destFile));
			int ch;
			while ((ch = input.read()) != -1)
				output.write(ch);
		} catch (IOException e) {
			log.error((new StringBuilder("Error writing stream to file: "))
					.append(destFile.getAbsolutePath()).toString());
			throw e;
		} finally {
			try {
				input.close();
			} catch (Exception e) {
			}
			output.close();
		}
	}

	public static void saveTextFile(String stringContent, File destFile)
			throws IOException {
		ensureFileAndPathExist(destFile);
		FileWriter writer = new FileWriter(destFile);
		writer.write(stringContent);
		writer.close();
	}

	public static void ensureFileAndPathExist(File file) throws IOException {
		file.getParentFile().mkdirs();
		file.createNewFile();
	}

	public static boolean deleteDir(File dir) {
		if (dir == null)
			return false;
		File candir;
		try {
			candir = dir.getCanonicalFile();
		} catch (IOException e) {
			return false;
		}
		if (!candir.equals(dir.getAbsoluteFile()))
			return false;
		File files[] = candir.listFiles();
		if (files != null) {
			for (int i = 0; i < files.length; i++) {
				File file = files[i];
				boolean deleted = !file.delete();
				if (deleted && file.isDirectory())
					deleteDir(file);
			}

		}
		return dir.delete();
	}

}
